#include <stdio.h>
#include <stdlib.h>
#include <mqueue.h>

#include "retrait.h"
#include "ResChaineCond.h"
#include "partage_stock_ret.h"
#include "../utils/utils.h"
#include "../interface/messqueue.h"
#include "../interface/variablesglobales.h"
#include "../interface/constantes.h"

static mqd_t bal_erreurs;
static mqd_t bal_messages;
static mqd_t bal_retrait;

static unsigned short continuer = 1;
/**
 Initialisation de la tache
*/
void init_retrait() {
	// debug
	printf("[Retrait] Coucou le retrait \n");
	bal_erreurs = ouvrir_mqueue(BAL_ERREURS_NAME, O_WRONLY);
	bal_messages = ouvrir_mqueue(BAL_MESSAGES_NAME, O_WRONLY);
	bal_retrait = ouvrir_mqueue(BAL_RETRAIT_NAME, O_RDONLY);
}

/**
 Destruction des ressources utilisées
*/
void detruire_retrait() {
	mq_close(bal_erreurs);
	mq_close(bal_messages);
	mq_close(bal_retrait);
	pthread_mutex_destroy(&mut_stock);
}

void* retrait(void* parameter) {
	// non utilisé
	(void) parameter;
	init_retrait();
	while(continuer) {
		struct message msg_recu;
		unsigned short retrait_ok = 0;

		int taille_lue = lire_message(bal_retrait, &msg_recu);
		if (taille_lue == -1) {
			perror("[Retrait] Echec lire_message");
			exit(1);
		}

		if(msg_recu.type == ARRET) {
			// debug
			printf("[Retrait] Arrêt complet\n");
			break;
		}

		// des magic numbers pour les params?!
		printf("[Retrait] Demande de retrait: type: %ld \t nb pal A: %d \t B: %d \t quai: %d \n",
			msg_recu.type, msg_recu.params[0], msg_recu.params[1], msg_recu.params[2]);
		printf("[Retrait] Stock actuel: A: %d\t B: %d\n",
				g_compteur_stock[NUM_A], g_compteur_stock[NUM_B]);

		// NUM_A et NUM_B définis dans interface/constantes.h
		pthread_mutex_lock(&mut_stock);
		if( g_compteur_stock[NUM_A] >= msg_recu.params[0] && 
			g_compteur_stock[NUM_B] >= msg_recu.params[1] ) {
			
			g_compteur_stock[NUM_A] -= msg_recu.params[0];
			g_compteur_stock[NUM_B] -= msg_recu.params[1];
			retrait_ok = 1;
		}
		pthread_mutex_unlock(&mut_stock);
		if(retrait_ok==1) {
			//debug
			printf("[Retrait] retrait, A: %d\t B: %d\n",
				g_compteur_stock[NUM_A], g_compteur_stock[NUM_B]);

			struct message msg_retrait;
			msg_retrait.type = RETRAITOK;
			msg_retrait.params[0] = msg_recu.params[0];
			msg_retrait.params[1] = msg_recu.params[1];
			msg_retrait.params[2] = msg_recu.params[2];


			mq_send (bal_messages, (char *)&msg_retrait, sizeof(struct message), 1);
		} else {
			printf("[Retrait] err retrait, stock actuel: A: %d\t B: %d\n",
				g_compteur_stock[NUM_A], g_compteur_stock[NUM_B]);
			struct message msg_retrait;
			msg_retrait.type = ERRRETRAIT;

			mq_send (bal_messages, (char *)&msg_retrait, sizeof(struct message), 1);
		}
		
	}

	detruire_retrait();
	return 0;
}
